import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core'
import { ListBaseClass } from '@shared/classes/ListBaseClass'
import { NzMessageService } from 'ng-zorro-antd'
import { I18NService } from '@core'
import { Router, ActivatedRoute } from '@angular/router'
import { SettingsService } from '@delon/theme'
import { ACLService } from '@delon/acl'
import { OperationsService } from '../../operations-abstract.service'
import { CurrencyService } from '@shared/services/currency.service'
import { STColumn } from '@delon/abc'
import { ETransScene, ETradeChannel, ESearchType, ECardTradeChannel } from '@shared/enums'
import { Observable } from 'rxjs'
import { TradeAmountMaxValue, today } from 'app/utils/contraints'
import { Currency, EDateLimitEnum } from '@shared/interfaces/common'
import { ISearchSchema } from '@shared/interfaces/search'
import { openDownloadDialog } from 'app/utils/helpers'
import {
  IChargeBack,
  ChargeBackProcessTypeMap,
  ChargeBackStatusMap,
  ChargeBackTransCodeMap,
  ProcessFlagMap,
} from '@shared/interfaces/operation'
import { HelperService } from '@shared/services/helper.service'

@Component({
  selector: 'app-operation-charge-back',
  templateUrl: './list.component.html',
  styleUrls: ['../../../../shared/styles/table.less'],
})
export class ChargeBackListComponent extends ListBaseClass<any, any> implements OnInit {
  @ViewChild('transAmt') transAmt: TemplateRef<void>
  @ViewChild('insTpl') insTpl: TemplateRef<void>
  @ViewChild('agentTpl') agentTpl: TemplateRef<void>
  @ViewChild('merchantTpl') merchantTpl: TemplateRef<void>
  @ViewChild('storeTpl') storeTpl: TemplateRef<void>
  @ViewChild('tplCurrency') tplCurrency: TemplateRef<void>

  ChargeBackTransCodeMap = ChargeBackTransCodeMap
  ChargeBackProcessTypeMap = ChargeBackProcessTypeMap
  ProcessFlagMap = ProcessFlagMap

  transSceneEnum = ETransScene
  transChannelEnum = ETradeChannel
  math = Math // 引用使 htm 可以调用
  chargeAmtFrom: string // 交易金额从
  chargeAmtTo: string // 交易金额到

  selectedCurrency: Currency
  searchSchema: ISearchSchema[] = []
  columns: STColumn[] = []

  constructor(
    public msg: NzMessageService,
    public i18n: I18NService,
    public router: Router,
    public route: ActivatedRoute,
    public settings: SettingsService,
    public aclService: ACLService,
    private operateService: OperationsService,
    private currencyService: CurrencyService,
    private helperService: HelperService,
  ) {
    super(msg, i18n, route, router, settings)
  }

  ngOnInit() {
    this.initSearchParams()
    this.parseParams().subscribe(() => {
      this.queryTableDataWithParams()
      this.initColumns()
    })
    this.initialAAMSFilter()
  }

  initialAAMSFilter() {
    this.initAcquirer()
    this.initAgent()
    this.initMerchant()
    this.initStore()
  }

  queryTableDataWithParams(): void {
    this.loading = true
    this.operateService
      .getChargeBackList(this.params)
      .subscribe(this.renderList.bind(this), this.getListError.bind(this))
  }

  initSearchParams(): void {
    this.searchSchema = [
      {
        label: '差错日期',
        labelI18n: 'OPERATION.CHARGEBACK.DATE',
        index: ['createdAtFrom', 'createdAtTo'],
        type: ESearchType.dateRange,
        allowClear: false,
        dateLimitType: EDateLimitEnum.Month,
        value: [today, today],
      },
      {
        label: '订单号',
        labelI18n: 'TRADE.ORDER_NUM',
        index: 'orderNum',
        type: ESearchType.input,
        value: '',
      },
      {
        label: '差错金额',
        labelI18n: 'TRADE.CHARGEBACK.AMT',
        index: ['minDisputeAmt', 'maxDisputeAmt'],
        component: this.transAmt,
        customFunc: () => [this.chargeAmtFrom, this.chargeAmtTo],
      },
      {
        label: '交易币种',
        labelI18n: 'GENERAL.INFO.TRANSACTION_CURRENCY',
        index: 'transCurr',
        component: this.tplCurrency,
        customFunc: () => (this.selectedCurrency ? this.selectedCurrency.code : ''),
      },
      {
        label: '渠道',
        labelI18n: 'GENERAL.INFO.CHANNEL',
        index: 'cardBrand',
        type: ESearchType.selection,
        options: this.helperService.generateOptionsFromEnum(ECardTradeChannel),
      },
      {
        label: '检索参考号',
        labelI18n: 'OPERATION.TRADE.RETRIEVAL_REFNUM',
        index: 'retrievalRefNum',
        type: ESearchType.input,
      },
      {
        label: '卡号',
        labelI18n: 'TRADE.CARD_NUMBER',
        index: 'acctNum',
        type: ESearchType.input,
      },
      {
        label: '授权码',
        labelI18n: 'TRADE.AUTH_CODE',
        index: 'authCode',
        type: ESearchType.input,
      },
      {
        label: 'ARN',
        labelI18n: 'OPERATION.CHARGEBACK.ARN',
        index: 'acqReferData',
        type: ESearchType.input,
      },
      {
        label: '原因代码',
        labelI18n: 'OPERATION.CHARGEBACK.REASONCODE',
        index: 'reasonCode',
        type: ESearchType.input,
      },
      {
        label: '差错类型',
        labelI18n: 'OPERATION.CHARGEBACK.TRANSCODE',
        index: 'transCode',
        type: ESearchType.selection,
        options: this.helperService.generateOptionsFromEnum(ChargeBackTransCodeMap),
      },
      {
        label: '处理方式',
        labelI18n: 'OPERATION.CHARGEBACK.HANDLEMETHOD',
        index: 'processType',
        type: ESearchType.selection,
        options: this.helperService.generateOptionsFromEnum(ChargeBackProcessTypeMap),
      },
      {
        label: '状态',
        labelI18n: 'GENERAL.INFO.STATUS',
        index: 'processFlag',
        type: ESearchType.selection,
        options: this.helperService.generateOptionsFromEnum(ChargeBackStatusMap),
      },
      {
        label: '机构',
        labelI18n: 'GENERAL.BIZ_LEVEL.INSTITUTION',
        index: 'insCode',
        component: this.insTpl,
        customFunc: () => (this.selectedAcquirer ? this.selectedAcquirer.code : ''),
      },
      {
        label: '集团',
        labelI18n: 'GENERAL.BIZ_LEVEL.AGENT',
        index: 'agentCode',
        component: this.agentTpl,
        customFunc: () => (this.selectedGroup ? this.selectedGroup.code : ''),
      },
      {
        label: '商户',
        labelI18n: 'GENERAL.BIZ_LEVEL.MERCHANT',
        index: 'intMerCode',
        component: this.merchantTpl,
        customFunc: () => (this.selectedMerchant ? this.selectedMerchant.code : ''),
      },
      {
        label: '门店',
        labelI18n: 'GENERAL.BIZ_LEVEL.STORE',
        index: 'intStoreCode',
        component: this.storeTpl,
        customFunc: () => (this.selectedStore ? this.selectedStore.code : ''),
      },
    ]
  }

  initColumns(): void {
    this.columns = [
      {
        type: 'link',
        title: '案例编号',
        index: 'disputeNum',
        i18n: 'OPERATION.CHARGEBACK.CASEID',
        className: 'text-center',
        width: '250px',
        fixed: 'left',
        click: this.goDetail.bind(this),
      },
      {
        title: '门店名称',
        index: 'storeName',
        i18n: 'GENERAL.STORE.NAME',
        width: '150px',
        className: 'text-center',
      },
      {
        title: '差错日期',
        index: 'id.fileDate',
        i18n: 'OPERATION.CHARGEBACK.DATE',
        width: '150px',
        className: 'text-center',
      },
      {
        title: '差错类型',
        i18n: 'OPERATION.CHARGEBACK.TRANSCODE',
        className: 'text-center',
        width: '100px',
        render: 'chargeBackTransCode',
      },
      {
        title: '渠道',
        i18n: 'GENERAL.BIZ_LEVEL.CHANNEL',
        className: 'text-center',
        width: '100px',
        render: 'transChannel',
      },
      {
        title: '差错金额',
        i18n: 'TRADE.CHARGEBACK.AMT',
        className: 'text-center',
        width: '100px',
        render: 'transAmt',
      },
      {
        title: '状态',
        i18n: 'GENERAL.INFO.STATUS',
        type: 'badge',
        className: 'text-center',
        width: '100px',
        fixed: 'right',
        render: 'status',
      },
    ]
  }

  getDecimalByCurrencyCode(currCode: string): Observable<number> {
    return this.currencyService.getDecimalByCode(currCode)
  }

  /** 交易金额校验 */
  validateTransAmt() {
    const transAmtFromVal = this.chargeAmtFrom as any
    const transAmtToVal = this.chargeAmtTo as any

    if (
      (!isNaN(transAmtFromVal) &&
        (transAmtFromVal > Number.MAX_SAFE_INTEGER || transAmtFromVal > TradeAmountMaxValue)) ||
      (!isNaN(transAmtToVal) && (transAmtToVal > Number.MAX_SAFE_INTEGER || transAmtToVal > TradeAmountMaxValue))
    ) {
      this.msg.error(this.trans('VALIDATION.MAX_VALUE', { value: TradeAmountMaxValue }))
      this.searchValid = false
      return
    }

    if (!isNaN(transAmtFromVal) && !isNaN(transAmtToVal) && transAmtFromVal > transAmtToVal) {
      this.msg.error(this.trans('TRADE.MIN_AMT_LTE_MAX_AMT'))
      this.searchValid = false
      return
    }

    this.searchValid = true
  }

  checkSearchParamsValidation(): boolean {
    const transAmtFromVal = parseInt(this.chargeAmtFrom, 10)
    const transAmtToVal = parseInt(this.chargeAmtTo, 10)

    if (!isNaN(transAmtFromVal) || !isNaN(transAmtToVal)) {
      if (!this.selectedCurrency) {
        this.msg.error(
          this.trans('VALIDATION.REQUIRED_SELECT', { name: this.trans('GENERAL.INFO.TRANSACTION_CURRENCY') }),
        )
        return false
      }
    }
    return this.searchValid
  }

  download(): void {
    this.operateService.getChargeBackReport(this.params).subscribe(data => {
      const { url } = data
      openDownloadDialog(url, '下载报表')
    })
  }

  private goDetail(record: IChargeBack): void {
    const { disputeNum } = record
    this.router.navigate([`../${disputeNum}`], { relativeTo: this.route })
  }
}
